/*************************************************************************************
 *
 *	模块名称 : Linux函数概要信息查询模块
 *	文件名称 : funbrief.c
 *	版   本 : V1.0
 *	说   明 : 根据用户输入单词查找词典并打印单词类型和释义。
 *	修改记录 :
 *		     版本号       日期         作者        说明
 *	         V0.9     2022-05-20      YT        发布初始版本, 可以完成基本功能.
             V1.0     2022-05-20      YT        在 fbPrintFunBriefFile 函数中增加打印选项 -d 
                                                    如果只输入函数名, 则只打印概要信息
                                                    如果输入函数名和 -d, 则打印详细信息
 *
 *	Copyright (C), 2022-2030, xxxx
 *
 *************************************************************************************/

#include "inc.h"
#include "funbrief.h"
#include "funbrieflist.h"



int fbIsExitWord(const char strWord[])
{
    return strcmp( strWord, STR_EXIT );
}

void fbFindFun( const char strFunName[], int *piIndex, char *pcPrintOption )
{
    *piIndex = -1;        // 初始值设置为 没有找到
    *pcPrintOption = 0;   // 初始值设置为 默认打印选项

    // 字符串 strFunName 包含函数名称(也可能包含 打印选项)
    // 循环在 词典条目 中查找匹配的 函数词典条目, 设置所匹配的 词典条目数组 下标, 并设置 打印选项 
    int i;
    for ( i = 0; i < g_FunBriefListNum; i++ )
    {
        // 判断函数名是否匹配 词典条目
        if ( 0 == strncmp( strFunName, g_FunBriefList[i].strFunName, strlen(g_FunBriefList[i].strFunName) ) )
        {
            *piIndex = i ;      // 函数名匹配, 设置 下标 为有效值

            // 如果 输入字符串 的长度大于 词典条目中的函数名称, 则有可能包含 有效打印选项
            int iStrLenInputFunName = strlen( strFunName );
            int iStrLenDictFunName  = strlen( g_FunBriefList[i].strFunName );
            if ( iStrLenInputFunName > iStrLenDictFunName )
            {
                // 判断 输入字符串 最后两个字符 是否为 "-d"
                if ( strncmp( &strFunName[iStrLenInputFunName - 2], "-d", 2) == 0 )
                {
                    *pcPrintOption = 'd';
                }
            }

            break;
        }
    }
}

// 因为打印 函数概要信息文件 的代码比较多, 将此段代码做了封装
static void fbPrintFunBriefFile( const int iIndex, const char cPrintOption );

void fbPrintFunInformation( const int iIndex, const char cPrintOption)
{
    // 检查 iIndex 的合法性
    if( ( iIndex < 0 ) || ( iIndex > (g_FunBriefListNum-1) ) )
    {
        printf( "***** NULL fun name ******\n" );
        return;
    }

    printf( "##########################################################################################\n" );

    // 打印 函数名称, 函数所在Linux manual手册的篇章, 函数原型
    printf( "Function Name  : %s\n", g_FunBriefList[iIndex].strFunName );
    printf( "Linux Manual # : %d\n", g_FunBriefList[iIndex].iManIndex );
    printf( "Prototype      : %s\n", g_FunBriefList[iIndex].strFunPrototype );
    printf( "Brief          : %s\n", g_FunBriefList[iIndex].strFunBrief );
    printf( "------------------------------------------------------------------------------------------\n" );

    int i;
    char *pstrList;

    // 打印 函数相关头文件列表
    printf( "Head File: \n" );
    for ( i = 0; i < MAX_HAED_LIST_NUM; i++ )
    {
        pstrList = g_FunBriefList[iIndex].pstrHeadList[i];
        if( pstrList == NULL )
        {
            break;
        }
        printf( "\t%s\n", pstrList );
    }

    // 打印 函数相关示例代码列表
    printf( "Demo File: \n" );
    for ( i = 0; i < MAX_DEMO_LIST_NUM; i++ )
    {
        pstrList = g_FunBriefList[iIndex].pstrDemoList[i];
        if( pstrList == NULL )
        {
            break;
        }
        printf( "\t%s\n", pstrList );
    }

    // 打印 函数概要信息文件内容
    fbPrintFunBriefFile( iIndex, cPrintOption );

    printf( "\n##########################################################################################\n" );

}

static void fbPrintFunBriefFile( const int iIndex, const char cPrintOption )
{
    // 如果 函数概要信息文件 有效, 则打印 文件名 和 文件内容 (默认不打印内容, 需要根据命令选项 -d 判断)
    if ( g_FunBriefList[iIndex].strBriefFile != NULL )
    {
        printf( "------------------------------------------------------------------------------------------\n" );
 //       printf( "Fun Brief File: \n\t%s\n", g_FunBriefList[iIndex].strBriefFile ); 
 //       printf( "------------------------------------------------------------------------------------------\n" );
        
        // 如果 打印选项为 'd', 则打印 函数概要文件 的内容
        if ( 'd' == cPrintOption )
        {
            // 如果没有设置 函数概要文件, 则直接返回
            if ( g_FunBriefList[iIndex].strBriefFile == 0 )
            {
                return;
            }

            // 打印 函数概要文件 内容
            FILE *fpSrc = fopen( g_FunBriefList[iIndex].strBriefFile, "r" );
            if( NULL == fpSrc )
            {
                printf("Fail to open file %s", g_FunBriefList[iIndex].strBriefFile );
                return;
            }
            
            char strReadBuffer[500] = {0};
            char *pRet;
            while ( NULL != ( pRet = fgets( strReadBuffer, 
                                            sizeof(strReadBuffer), 
                                            fpSrc) ) )
            {
                printf("%s", strReadBuffer );
            }

            if( ferror(fpSrc) )
            {
                perror("Fail to fgets");
                return;
            }

            fclose(fpSrc);    
        }
    }

}

